/*
 * Add some prototype methods
 */
Date.prototype.countdown = function(){

	var utc = Date.now() 
	utc = utc + (this.getTimezoneOffset() * 60 * 1000);
	var time = Math.floor((this.getTime() - utc) / 1000);
	if(arguments[0])
	{
		var days, hours, minutes, seconds, rm, str;
		
		days = Math.floor(time / 86400);
		rm = (time % 86400);
		hours = Math.floor(rm / 3600);
		rm = rm % 3600;
		minutes = Math.floor(rm / 60);
		seconds = rm % 60;
		
		str = ((days > 0) ? days + ' Days' : '') + ((days > 1) ? 's ' : ' ');
		str += ((hours > 0) ? hours + ' Hour' : '') + ((hours > 1) ? 's ' : ' '); 
		str += ((minutes > 0) ? minutes + ' Minute' : '') + ((minutes > 1) ? 's ' : ' ');
		str += ((seconds > 0) ? seconds + ' Second' : '') + ((seconds > 1) ? 's' : '');
		return str;
	}
	else
	{
		return time;
	}	
}

Enumerable.findAllbyGrep = function(grep)
{
if(Object.isString(grep))
{
grep = eval(grep);
}
var reject = arguments[2] || false;
var key = arguments[1] || false;
var filter = new RegExp(grep);
var search = function(s){
	return filter.match((key) ? s[key] : s);
};

return this[(reject) ? 'reject' : 'findAll'](search);
};

Object.extend(Array.prototype, Enumerable); 

var Ebay = {CategoryChooser: Class.create({
cid: 0,
pid: 0,
store: [],
level: 1,
picked: false,
initialize: function(){
    Object.extend(this, arguments[0] || {});

    this.initialiseElements();
    this.initialiseEvents();
    this.getCategories(this.cid, 'cid');
},
initialiseElements: function(){
    this.elBack = new Element('div', {id : 'chooseCategory-back'}).update('Back');
    this.elContinue = new Element('span').update('<img src="continue" alt="continue" />Choose Category').hide();
    this.el = new Element('ul', {class : 'categories'});

    this.container = new Element('div', {id : 'categoryChooser'}).insert(this.elBack).insert(this.el).insert(this.elContinue);
},
toElement: function()
{
    return this.container;
},
toggle: function()
{
    if(this.picked)
    {
        this.container.toggle();
    }
    return this;
},
hide: function()
{
    this.container.hide();
    return this;
},
initialiseEvents: function(){
    this.elBack.observe('click', function()
    {
        if(this.level > 1)
        {
            this.el.update();
            this.level--;
            document.fire('category:notpicked');
            if(this.store[this.level])
            {
                this.store[this.level].each(this.create.bind(this));
            }
            else
            {
                this.getCategories(this.pid, 'pid');
            }
        }
    }.bind(this));

    document.observe('category:notpicked', function(){
        this.picked = false;
            this.elContinue.hide();
    }.bind(this));
    document.observe('category:picked', function()
    {
        this.picked = true;
        this.el.update('<li cid="picked">Category Picked</li>');
        this.elContinue.show();
    }.bind(this));

    this.elContinue.observe('click', function(){
        if(this.picked)
        {
            document.fire('category:chosen');
        }
    }.bind(this));

    this.el.observe('click', function(e){
        var el = e.element();
        if(el.tagName.toUpperCase() == 'LI' && el.getAttribute('cid') != 'picked')
        {
            this.cid = el.getAttribute('cid');
            this.pid = el.getAttribute('pid');
            this.picked = false;
            this.level++;
            this.getCategories(this.cid);
        }
    }.bind(this));
},
getCategories: function(id, mode){
    new Ajax.Request('/ajax/getcategory/' + (mode || 'cid')+ '/' + (id || ''), {onSuccess: function(t){

        var data = t.responseJSON.categories;

        this.store[this.level] = data;

        if(data)
        {
            if(data.size() == 0)
            {
                return document.fire('category:picked');
            }
            this.el.update();
            this.level = data[0].level;
            this.pid = data[0].pid;
            data.each(this.create.bind(this));
        }

    }.bind(this)});
},
create: function(cat){
    var li = new Element('li', {cid: cat.cid, pid: cat.pid});
        this.el.insert(li.update(cat.name));
}
}),
UploadImageForm: Class.create({
temp: [],
initialize: function ()
{
    this.imagebox = $('imageBox');
    this.form = $('uploadImages');

    this.iframe = new Element('iframe', {id: 'upload_iframe', src: '', name: 'upload_iframe'}).hide();
    this.form.insert(this.iframe);

    this.el = $('uploadPhotos');
    this.initialiseEvents();
    this.intiailiseDrop();
    if(arguments[0])
    {
        var images = arguments[0];
        images.each(this.addImage.bind(this));
    }
},
intiailiseDrop: function()
{
    Droppables.add('backdrop', {
    accept: 'listingImage',
    onDrop: function(el, drpel) {

        var params = {filename: el.getAttribute('filename')};
        if(el.getAttribute('pid'))
        {
            params.pid = el.getAttribute('pid');

        }
        el.fade({to: 50});
        this.imgRemoved = el;
        new Ajax.Request('/ajax/removeimage/', {parameters: {json : Object.toJSON(params)}, onSuccess: this.removeImage.bind(this)});
    }.bind(this)
    });

},
removeImage: function(t)
{
    if(t.responseJSON.status)
    {
        this.imgRemoved.fade({to:0, afterFinish: function(){this.imgRemoved.remove()}.bind(this)});
    }
},
initialiseEvents: function()
{
    this.iframe.observe('load', function()
    {
        this.temp = this.iframe.contentWindow.json.images;
        this.el.fire('images:uploaded');
    }.bind(this));

    this.el.observe('images:uploaded', function()
    {
        if(!this.temp) { return;}
        this.temp = $A(this.temp);
        this.temp.each(this.addImage.bind(this));
        this.form.reset();
    }.bind(this));
},
addImage: function(image)
{
    template = new Template('<img src="/host/#{filename}" class="listingImage" id="image-#{filename}" alt="image" filename="#{filename}" pid="#{pid}"/>');
    this.imagebox.insert(template.evaluate(image));
    var el = $('image-' + image.filename);
    new Draggable(el, {revert: 'failure', ghosting: true, onStart: function(e){e._clone.hide();}});
}
}),
Editor: Class.create({
current: 0,
createField: function(title, field)
{
    return new Element('Div').insert( new Element('Label', {for: field}).update(title + ':') );
},
slides:[function()
    {
        this.categoryChooser = new Ebay.CategoryChooser({
        cid: this.listing.cid,
        pid: this.listing.cid});

        document.observe('category:chosen', function(){
            this.forward();
        }.bind(this));

        return {title: 'Choose Category', body: this.categoryChooser};
    },
    function()
    {
        var form = new Element('Form', {id : 'editor'});
        form.insert(this.createField('Title', 'title').insert(new Element('Input', {id: 'title', type: 'text', value: this.listing.title})))
            .insert(this.createField('Description', 'description').insert(new Element('Textarea', {id: 'description'}).update(this.listing.description)))
            .insert(this.createField('Start Price', 'startPrice').insert(new Element('Input', {id: 'startPrice', type: 'text', value: this.listing.startPrice})))
            .insert(this.createField('Duration', 'duration').insert(new Element('Input', {id: 'duration', type: 'text', value: this.listing.duration})))
            .insert(this.createField('Delivery', 'delivery').insert(new Element('Input', {id: 'delivery', type: 'text', value: this.listing.delivery})))
            .insert(new Element('Span').addClassName('submit').update('Submit').observe('click', function(){this.up('form').fire('form:submit'); }));
            this.form = new MyForm(form, {submit: function(){
                this.data = this.el.serialize(true);
                new Ajax.Request('/ajax/edit/submit/', {parameters: {json : Object.toJSON(this.data)}, onSuccess: this.success.bind(this)});
            }});


            return {title: 'Create the listing', body: form};
    }],
initialize: function(listing){
    this.listing = listing;
    this.initialiseElements();
    this.initialiseEvents();
    this.display(0);
    },
initialiseEvents: function()
{

},
initialiseElements: function(){
    this.el = new Element('div', {id : 'editor'});
},
display: function(i)
{
    var slide = this.slides[i].bind(this)();
    this.el.update('<div class="title">' + slide.title + '</div>');
    this.el.insert(slide.body);
},
forward: function()
{
    this.current++;
    this.display(this.current);
},
back: function()
{
    this.current--;
    this.display(this.current);
},
toElement: function(){
    return this.el;
}
})
};

var Task = Class.create({
  name: null,
  key: '',
  el: null,
  initialize: function(name)
  {
    var defaults = {
        job:null,
        show: false,
        icon: 'images/question.png'
    };
    this.name = name;
	this.key = (arguments[1] && arguments[1].key) ? arguments[1].key : this.name.toLowerCase();
    this.options = Object.extend(defaults, arguments[1] || {});
  },
  createEvents: function(el) {
    this.el.observe('mouseup', this.options.job || function(){});
  },
  toElement: function() {
    this.el = new Element('div', {id: ('task-' + this.key), class: 'task'});
    this.el.insert(new Element('img', {src: '/' + this.options.icon, alt: this.name}));
    this.el.insert(new Element('span'));

    if(!this.options.show)
    {
        this.el.hide();
    }
    //this.el.down('span').insert(this.name);
    this.createEvents();
    return this.el;
  }
  });

var MyForm = Class.create({
    init: function(){},
    initialize: function(el){
        this.el = $(el);

        Object.extend(this, arguments[1] || {});
        this.init();
        this.el.observe('form:submit', function(){
        this.send();
        }.bind(this));

    },
    send: function(params){
        this.el.fade({to: 0.7});
        this.submit(params);
        this.el.disable();
    },
    process: function(t){
        this.el.getElementsBySelector('div.errors').invoke('remove');
        this.el.enable();
        this.el.appear({from: 0.7, to: 1});

        var response = t.responseJSON;

        if(response)
        {
            if(response.errors)
            {
                this.response = response;
                this.validate();
            }
            else
            {
                this.success(t);
                document.fire('form:success');
            }
        }

    },
    validate: function(){
        var errors = $H(this.response.errors);
        errors.each(function(pair) {
           var messages = '<ul>';
           messages += $H(pair.value).values().collect(function(s)
           {
                return '<li>' + s + '</li>';
           });
           messages += '</ul>';

            //Insert the errors
            $(pair.key).up('div').insert('<div class="errors">' + messages + '</div>', {position: 'bottom'});
        });
    }
    });
var Dialog = Class.create({
    options: {
        opacity: 0.8,
        left: '10%',
        top: '10%',
        width: '80%',
        height: '80%'
    },
    initialize: function(name){
        
        this.options = arguments[1] || this.options;
		app.dialog = this;
        this.dialog = new Element('div', {id : 'dialog-' + name, name: name});
        this.dialog.setStyle({left: this.options.left, top: this.options.top, width: this.options.width, height: this.options.height});
        this.el = new Element('div', { id:"dialogContent"});


        this.dialog.addClassName('dialog').hide().insert('<div id="closeDialog"></div>').insert(this.el);

        //If the backdrop doesn't exist create one
        this.backdrop = ($('backdrop') === null) ? new Element('div', {id: 'backdrop'}).hide() : $('backdrop');

        $(document.body).insert(this.dialog).insert(this.backdrop);

        $('closeDialog').observe('mousedown', function()
        {
            document.fire('dialog:close');
        });
	
		document.observe('dialog:close', this.close.bind(this));
		
        this.backdrop.appear({to: this.options.opacity, queue: { position: 'front', scope: 'dialog'}});
        this.dialog.appear({queue: { position: 'end', scope: 'dialog'}});
    },
    destroy: function()
    {
        this.dialog.remove();
    },
    close: function()
    {
        this.dialog.fade({afterFinish: this.destroy.bind(this), queue: { position: 'front', scope: 'dialog'}});
        this.backdrop.fade({queue: { position: 'end', scope: 'dialog'}});
    }
});

var Table = Class.create({
    el: null,
    rows: 0,
    params: {
        rowClass : 'row',
        rowRef: '#{rowId}'
    },
    dblClick: 0,
    initialize: function(id, params)
    {
        this.params = Object.extend(this.params, params);

        this.header = new Element('thead');
		var header = '<tr class="header">';
        var row = '<tr class="' + ( this.params.rowClass) + '" row="' + (this.params.rowRef) + '" >';
        this.params.fields.each(function(s)
        {
            header += '<th ';
			//Find any fields from the ex
			if(Object.isUndefined(s.content))
			{
				s.content = '';
			}
			
			var fields = [];
			s.content.gsub('#{(.*?)}', function(f){
				fields[fields.size()]= f[1];
			});
			if(s.key)
			{
				fields[fields.size()] = s.key;
			}
			if(fields.size() > 0)
			{
				header += 'fields="' + fields.join(' ') + '" '; 
			}
            if(s.sortable)
            {
                header += ' class="sortable" ';
            }
            header += '>' + s.title + '</th>';
            row += '<td>' + s.content + '</td>';
        });
        header += '</tr>';
        row += '</tr>';

        this.rowTemplate = new Template(row);

		this.body = new Element('tbody');
        this.el = new Element('table',{id: id}).insert(this.header).insert(this.body);
		this.header.insert(header);
        this.initialiseRows();
        this.initialiseEvents();
    },
    sortRows: function(element){
        var mode, el = (element.tagName.toUpperCase() != 'TH') ? element.up('th.sortable') : element;
        if(!el.hasClassName('sortable'))
        {
            return;
        }
		//
        switch(true)
        {
            default: 
			mode = 'asc';
			 //Carry on just as if it were previously a 'asc'
            case el.hasClassName('asc'):
            mode = 'desc'
            break;
            case el.hasClassName('desc'):
            mode = 'asc';
            break;
        }
		this.el.select('th.asc', 'th.desc').each(function(s){
		s.writeAttribute({class: 'sortable'}).down('div').remove();
		});
		
		el.addClassName(mode).insert(new Element('div'));


        var rows = this.el.getElementsBySelector('tr.' + this.params.rowClass);
        var result = [];        
		
        //Sort function
        result = rows.sortBy(function(s)
        {             
			var val = s.childNodes[el.cellIndex];
			val = (val.readAttribute('value')) ? val.readAttribute('value') : val.textContent;
			
			return val;
        });
		
        if(mode != 'desc')
        {
            result.reverse();
        }
        result.each(function(s){
            this.body.insert(s);
        }.bind(this));

        this.el.fire('table:sorted');
    },
	getColumnIndex: function(key)
	{
		return this.el.down('th[fields="' + key + '"]').cellIndex;	
	},
	getRow: function(id)
	{
		return this.el.down('tr[row=' + id + ']')
	},
    selectRow: function(el){
        var row = el.up('tr');
        if(row.hasClassName('selected'))
        {
            row.removeClassName('selected');
        }
        else
        {
            row.addClassName('selected');
        }
        this.el.fire('table:selectionchanged');
    },
    initialiseEvents: function() {

        this.el.observe('mouseup', function(e){
        var el = e.element();
		
		if(this.params.delegator && this.params.delegator(e))
		{
			return;
		}
        //Check whether the element that has been clicked is a row that has a listing by navigating up the dom tree to a table row ancestor
        switch(true)
        {
            case el.up('tr').hasClassName(this.params.rowClass): this.selectRow(el); break; //Select Rows
            case el.up('tr').hasClassName('header'): this.sortRows(el); break;
            default: return;
        }

        }.bind(this));

    },
	insert: function(data)
	{
		if(Object.isArray(data))
		{
			data.each(this.insert.bind(this));
			return;
		}

		this.body.insert(this.rowTemplate.evaluate(data));
		this.el.fire('table:updated');
	},
    updateRow: function(id)
    {   var row = '';
	
        this.params.fields.each(function(s)
        {
            row += '<td>' + s.content + '</td>';
        });
		
		var item = this.params.data.find(function(s){ return s.id == id });
        row = new Template(row);
        this.getRow(id).update(row.evaluate(item) );
		this.el.fire('table:updated');
    },
    initialiseRows: function() {
        var rows = '';
		this.insert(this.params.data);
    },
	invertSelection: function()
	{
		return this.el.select('tr.row:not(tr.selected)');
	},
    selectNone: function()
    {
        this.el.getElementsBySelector('tr.' + this.params.rowClass).invoke('removeClassName', 'selected');
        this.el.fire('table:selectionchanged');
    },
    selectAll: function()
    {
        this.el.getElementsBySelector('tr.' + this.params.rowClass).invoke('addClassName', 'selected');
        this.el.fire('table:selectionchanged');
    },
    getSelection: function()
    {
        return this.el.getElementsByClassName('selected');
    },
    toElement: function()
    {
        return this.el;
    }
});

var Notify = Class.create({
initialize: function(message)
{
	this.yes = arguments[1] || false;
	this.no =  arguments[2] || false;
	if(this.yes)
	{
		if(confirm(message))
		{
			this.yes();
		}
		else
		{
			this.no();		
		}
	}
	else
	{
		alert(message);
	}
} });

var TextboxPoller = Class.create({
observer: false,
options: {
	delay: 0.5
 },
initialize: function(el, action){
	this.el = $(el);
	this.action = action;
	
	Object.extend(this.options, arguments[2] || {});
	this.el.observe('keypress', function()
	{
		if(this.observer) clearTimeout(this.observer);
		this.observer = setTimeout(this.action.curry(this.el), this.options.delay * 1000);
	}.bind(this));
}
});

var App = Class.create({
  listings: {},
  job:
  {
   current: 0,
   jobs: []
  },
  forms: {},
  dialog:null,
  tasks: $H({}),
  selection: [],
  initialize: function(){
    this.listings = json.listings;
	Object.extend(window, json.app);
	this.prepareListings();
	
    this.table = new Table('listings',{
      fields:[
        {  title:'Listing Title', content: '#{title}', sortable: true },
        {  title:'Description', content: '#{description}'},
        {  title:'Bids', content: '#{bids}', sortable: true},
		{  title:'Watches', content: '#{watches}', sortable: true},
		{  title:'Current Bid', content: currencySymbol + '#{currentPrice}', sortable: true},
		{  title:'Time Left', key: 'finishes', sortable: true},
		{  title:'Status', key: 'status', content: ''}
        ],
      data: this.listings, rowRef: '#{id}', delegator: this.delegator.bind(this)});

    $('content').insert(this.table);
	
	
    this.initialiseEvents();
	this.initialiseTasks();
	this.initialiseStatus();
	this.initialiseTimers();
	
	this.updateTable();
	this.updateStatus();
	this.updateTimes();
  },
  prepareListings: function()
  {
	this.listings.each(function(s)
	{
		this.updateListing(s);
	}.bind(this));
  },
  filterchain: [],
  initialiseEvents: function() {
    this.table.el.observe('table:selectionchanged', function(e)
    {
        this.selection = this.table.getSelection();
        this.toggleTasks();
    }.bind(this));
	
	$('filterbar').observe('click', function(e)
	{
		var el = e.element();
		if(el.tagName.toUpperCase() == 'LI')
		{
			$('filterbar').down('li.enabled').removeClassName('enabled');	
			
			this.search.el.value = "";
			$('filterbox').checked = false;
			
			this.filteredResult = [];
			
			this.table.el.select('tr.row').invoke('show');
			el.addClassName('enabled');
			
			this.filterchain = $H(el.readAttribute('filter').toQueryParams());
			this.filterchain.each(function(s)
			{
				this.filteredResult = this.filterListings(s.value, s.key, true, this.filteredResult);
			}.bind(this));
		}
	}.bind(this));
	
	$('filterbox').observe('click', function(e)
	{
		if(e.element().checked)
		{
			this.filterListings(this.search.el.value, 'title', true, this.filteredResult);
		}
		else
		{
			this.filteredResult.pluck('id').each(function(id)
			{
				this.table.getRow(id).show();
			}.bind(this));
		}
	}.bind(this));
	
	this.search = new TextboxPoller('searchbox', function(el)
	{
		this.table.el.select('tr.row').invoke('removeClassName', 'selected');
		if(el.value == "")
		{
			return;
		}
		var filter = $('filterbox').checked;
		
		this.filterListings(el.value, 'title', filter, this.filteredResult);
	}.bind(this));
		
	this.table.el.observe('table:updated', this.updateTable.bind(this));
	this.table.el.observe('table:sync', function()
	{
		this.updateTable();
		this.filterchain.each(function(s)
		{
			this.filteredResult = this.filterListings(s.value, s.key, true, this.filteredResult);
		}.bind(this));
	}.bind(this));
  },
  delegator: function(e)
  {
	var el = e.element();
	//Check whether the element that has been clicked is a row that has a listing by navigating up the dom tree to a table row ancestor
	if(el.hasClassName('status-icon') && !el.hasClassName('done'))
	{
		switch(el.readAttribute('alt'))
		{
			case 'paymentReceived': 
				var mark = 'paid';
			break;
			case 'dispatched': 
				var mark = 'dispatched';
			break;
			default: return;
		}
		var id = el.up('tr.row').readAttribute('row');
		new Ajax.Request('/ajax/mark/' + mark + '/' + id, {onSuccess: function(t)
		{
			var response = t.responseJSON;
			if(response && response.status)
			{
				this.updateListing(response.listing);
			}
		}.bind(this)});
		return true;
	}
	return false;
  },
  initialiseTasks: function() {
    var tasks = [
    new Task('Create', {job: this.createListing.bind(this), show: true}),
    new Task('View', {job: this.viewListing.bind(this)}),
    new Task('Edit', {job: this.editListing.bind(this)}),
	new Task('Relist', {job: this.relist.bind(this)}),
	new Task('Revise', {job: this.reviseListings.bind(this)}),
    new Task('Remove', {job: this.removeListings.bind(this)}),
    new Task('Submit', {job: this.submitListings.bind(this)}),
	new Task('Send Invoice', {key: 'sendInvoice', job: this.sendInvoice.bind(this)}),
    new Task('Print Invoice', {key: 'printInvoice', job: this.printInvoice.bind(this)}),
	new Task('Print Postage', {key: 'printPostage', job:this.printPostage.bind(this)})
	];

	tasks._each(function(task){
    $('tasks').insert(task);
	
    this.tasks.set(task.key, task);
    }.bind(this));
  },
  printInvoice: function()
  {
  var items = {listings: []};
	$A(this.selection).each(function(t){
		items.listings[items.listings.size()] = this.findListing(t.readAttribute('row')).id;
	}.bind(this));
	
  var form = new Element('form', {method: 'post', target: '_blank', action: '/createinvoice'}).insert(new Element('input', {type: 'hidden', name: 'json', value: Object.toJSON(items)}));
  document.body.insert(form);
  form.submit();
  form.remove();
  },
  printPostage: function()
  {
	var items = {listings: []};
	$A(this.selection).each(function(t){
		items.listings[items.listings.size()] = this.findListing(t.readAttribute('row')).id;
	}.bind(this));
	
	var form = new Element('form', {method: 'post', target: '_blank', action: '/createpostage'}).insert(new Element('input', {type: 'hidden', name: 'json', value: Object.toJSON(items)}));
	document.body.insert(form);
	form.submit();
	form.remove();	
  },
  initialiseStatus: function() {

  },
  updateTable: function() {
	var stotal = 0, ftotal = 0;
	this.listings.each(function(s){
		if(s.status == 1 && s.bids > 0)
		{
			stotal += s.currentPrice;
		}
		else if(s.status > 2 && s.bids > 0)
		{
			ftotal += s.currentPrice;
		}		
	}.bind(this));
	$('status').down('div.sellingTotals').update('Selling Total - ' + currencySymbol + stotal);
	$('status').down('div.finishedTotals').update('Finished Total - ' + currencySymbol + ftotal);
  },
  initialiseTimers: function()
  {
	new PeriodicalExecuter(this.updateTimes.bind(this), 1);
  },
  updateStatus: function()
  {
	var colIndex = this.table.getColumnIndex('status');
	var icons = '<img src="/images/icons/paypal.gif" class="status-icon" alt="paypal">' +
				'<img src="/images/icons/paid.gif" class="status-icon" alt="paid">' +
				'<img src="/images/icons/paymentReceived.gif" class="status-icon" alt="paymentReceived">' +
				'<img src="/images/icons/dispatched.gif" class="status-icon" alt="dispatched">';
			
	this.listings.each(function(s)
	{		
		if(s.status < 3)
		{
			return;
		}
		var cell = this.table.getRow(s.id).cells[colIndex];
		cell.update(icons);
		cell.select('img').invoke('setStyle', {opacity:0.4});
		//Confirm by checking status
	
		if(s.status > 3)
		{
			cell.down('img[alt=paymentReceived]').setStyle({opacity:1}).addClassName('done');
			cell.down('img[alt=paid]').setStyle({opacity:1}).addClassName('done');
		}
		if(s.status == 5)
		{
			cell.down('img[alt=dispatched]').setStyle({opacity:1}).addClassName('done');
		}			
		
	}.bind(this));
  },
  updateTimes: function()
  {
	var colIndex = this.table.getColumnIndex('finishes');
	this.listings.each(function(s)
	{		//Confirm by checking status
		var val = 0, time;
		if(s.finishes)
		{
			time = s.finishes.countdown();
			if(time < 0)
			{
				time = 'Finished'
			}
			else
			{	
				val = time;

				time = (time < 60*60*24) ? s.finishes.countdown(true) : s.finishes.strftime('%Y-%m-%d %H:%M');
			}
		}
		else
		{
			time = '-';
		}

		this.table.getRow(s.id).cells[colIndex].update(time).writeAttribute({value: val});
	}.bind(this));
  },
  filteredResult: [],
  filterListings: function(value, key)
  {
	var filter = arguments[2] || false
	var src = (arguments[3] && arguments[3].size() > 0) ? arguments[3] : this.listings;

	var result = src.findAllbyGrep('/' + value + '/i', key, filter);
	if(filter)
	{//NOTE CHANGE
		result.pluck('id').each(function(id)
		{
			this.table.getRow(id).hide();
		}.bind(this));
		var result = src.findAllbyGrep('/' + value + '/i', key);
	}
	else
	{
		result.pluck('id').each(function(id)
		{
			this.table.getRow(id).addClassName('selected');
		}.bind(this));
	}
	
	return result;
  },
  findListing: function(id)
  {
    return this.listings.find(function(s){ return s.id == id});
  },
  formatListing: function(listing)
  {
	listing.created = $D(listing.created);
	listing.finishes = $D(listing.finishes);
	listing.submitted = $D(listing.submitted);
	return listing;
  },
  sendInvoice: function()
  {
	var notify = new Notify('Are you sure you want to send an invoice', function()
	{

	});
  },
  insertListing: function(listing)
  {
	this.listings.push(this.formatListing(listing));
	if(this.table)
	{
		this.table.el.fire('table:sync');
	}
  },
  updateListing: function(listing)
  {	
	Object.extend(this.findListing(listing.id), this.formatListing(listing));
	if(this.table)
	{
		this.table.el.fire('table:sync');
	}
  },
  sync: function()
  {
	new Ajax.Request('/ajax/sync', {onSuccess: function(t){
		var response = t.responseJSON;
        if(response && response.status)
        {
			response.listings.each(function(s){
	            app.updateListing(s);
	            app.table.updateRow(s.id);			
			});
		
		}
	} });
  },
  settingsTab: function()
  {
	$('listingsContent').hide();
	if($('settingsContent'))
	{
		var settingsContent = $('listingsContent');
		settingsContent.show();	
	}
	else
	{
		var settingsContent = new Element('div', {id: 'settingsContent'});
		$('main').insert(settingsContent);
		new Ajax.Updater(settingsContent, '/settings', {onSuccess: function()
		{
		settingsContent.show();	
		}});
	}	
  }, 
  viewListing: function()
  { 
    var el = this.selection[0];
    var pos = el.viewportOffset();
    new Dialog('view', {opacity: 0.3, width: '200px', height: '200px', left: pos[0] + 'px', top: pos[1] + 'px'} );
    var listing = this.findListing(el.readAttribute('row'));
    $('dialogContent').update('Viewing item - ' + listing.title);

  },
  createListing: function()
  {
    new Dialog('create');
    new Ajax.Updater('dialogContent', '/ajax/create/form', {evalScripts: true});
  },
  editListing: function()
  {
    var listing = this.findListing(this.selection[0].readAttribute('row'));
    new Dialog('edit');
     new Ajax.Updater('dialogContent', '/ajax/edit/form/' + listing.id, {evalScripts: true});

    //this.dialog.el.insert(new Ebay.Editor(listing));
  },
  relist: function()
  {
	var items = {listings: []};
	$A(this.selection).each(function(t){
		items.listings[items.listings.size()] = this.findListing(t.readAttribute('row')).id;
	}.bind(this));		
	new Ajax.Request('/ajax/relist', {parameters: {json : Object.toJSON(items)}, onSuccess: function(t){
		var response = t.responseJSON;
		var fees = [];
        if(response && response.status)
        {
			response.listings.each(function(s){
			fees[fees.size()] = s.fees;
			delete s.fees;
			this.updateListing(s);
			this.table.updateRow(s.id);			
			}.bind(this));
		}	
		
	}.bind(this)
	});
  },
  reviseListings: function()
  {
	
  },
  submitListings: function()
  {
	var mode = 'verify', items = {listings: []};
	if(arguments[0] == 'confirm')
	{
		mode = 'confirm';
		items.listings = Object.isArray(arguments[0]) ? arguments[0] : this.idList;
	}
	else
	{
		$A(this.selection).each(function(t){
			items.listings[items.listings.size()] = this.findListing(t.readAttribute('row')).id;
		}.bind(this));	
	}
	
	var verify = function(t){
		var response = t.responseJSON;
		var fees = [];		
		
        if(response && response.status)
        {
			new Dialog('Submit');
			var section = new Element('div', {class : 'section'});
			
			if(response.warnings.size() > 0)
			{
				var warnings = new Element('div').insert("<h3>Warnings</h3><p>Please observe the warnings and make changes" +
				"if necessary to the listing before submitting.</p><ul class=\"warning\"></ul>");
				response.warnings.each(function(s){
					var listing = this.findListing(s.id);
					
					warnings.select('ul.warning')[0].insert(new Element('li').insert(listing.title + ' : ' + s.message));
				}.bind(this));
				section.insert(warnings);
			}
			
			if(response.fees.size() > 0)
			{
				var fees = new Element('div').insert("<h3>Fees</h3><p>All items that may be sucessfully submited are shown" + 
				"below with associated fees</p><ul class=\"fees\"></ul>");
				var feeTotal = 0;
				this.idList = [];
				
				response.fees.each(function(s){
					var listing = this.findListing(s[0]), feeList = '';
							
					this.idList.push(s[0]);
					
					s[1].each(function(fee)
					{
						if(fee[0] == 'ListingFee')
						{
							feeTotal += parseFloat(fee[1]);
							return;
						}
						feeList += fee[0] + ' - ' + fee[1] + ',';
					});
					// report bug in prototype cannot use down
					fees.select('ul.fees')[0].insert(new Element('li').insert(listing.title + ' : ' + feeList));
				}.bind(this));
				fees.insert('Total Fees: &pound;' + feeTotal);
				section.insert(fees);
				
				var options = [{key: 'Cancel', action: 'app.dialog.close()'},
							   {key: 'Confirm &amp; Save', action: "app.submitListings('confirm')"}]; 
				var template = '<span class="submit" onclick="#{action}">#{key}</span>';
				var submit = new Element('div', {class: 'section'});
				options.each(function(s)
				{
					submit.insert(template.interpolate(s));
				});
				
				
			}
			else
			{
				section.insert('<b>No Listings could be submitted - <span onclick="app.dialog.close()">Close Window</span></b>');
			}
			this.dialog.el.insert(new Element('div', {class:'title'}).insert('Submission Fees and Warnings'))
			.insert(section).insert(submit);
			
		}	
	}.bind(this);
	
	var confirm = function(t)
	{
		var response = t.responseJSON;
		var fees = [];		
		
        if(response && response.status && response.listings)
        {
			response.listings.each(function(listing)
			{				
	            app.updateListing(listing);
			}.bind(this));
			app.dialog.close();
		}	
	}
	new Ajax.Request('/ajax/submit/' + mode, {parameters: {json : Object.toJSON(items)}, onSuccess: ((mode == 'confirm') ? confirm : verify).bind(this)});
  },
  removeListings: function()
  {
	var items = {listings: []};
	$A(this.selection).each(function(t){
		items.listings[items.listings.size()] = this.findListing(t.readAttribute('row')).id;
	}.bind(this));	
	
	new Ajax.Request('/ajax/remove', {parameters: {json : Object.toJSON(items)}, onSuccess: function(t){
		var response = t.responseJSON;
		var fees = [];
        if(response && response.status)
        {
			response.listings.each(function(id){
			delete this.findListing(id);
            this.table.getRow(id).remove();		
			}.bind(this));
		}	
	}.bind(this)
	});
  },
  toggleTasks: function() {
    var size = this.selection.length, tasks = [];
	// Check if all the selections of tasks are the same
	var statusTmp = false;
	
	$A(this.selection).each(function(t){	
		var status = this.findListing(t.readAttribute('row')).status;
		
		if(!statusTmp || status == statusTmp)
		{
			statusTmp = status;
		}
		else
		{
			statusTmp = false;
			throw $break;
		}
	}.bind(this));
    if(size == 1 || statusTmp !== false)
    {
        var listing = this.findListing(this.selection[0].readAttribute('row'));
        switch(listing.status)
        {
            case 0: tasks = ['view', 'edit', 'submit', 'remove']; break; // Created
            case 1: tasks =['view']; break; //  Submitted 
            case 2: tasks =['view', 'remove']; //Finished no bids
				if(!listing.relist)
				{
					tasks.push('relist');
				}
				else
				{
					tasks.push('submit');
				}
			break; 
            case 3: tasks =['sendInvoice']; break; // Sold
            case 4:  // Payment Recieved
				tasks =['printInvoice', 'printPostage'];
				break;
			case 5: break; // Shipped
            default: tasks = ['view', 'edit', 'submit', 'remove'];
        }
    }
    else
    {
        tasks = ['create'];
    }
	
	if(size > 1)
    {
        tasks.slice(tasks.indexOf('view'), 1);
		tasks.slice(tasks.indexOf('edit'), 1);
		tasks.slice(tasks.indexOf('revise'), 1);
    }
	
    this.tasks.values().pluck('el').invoke('hide');
    tasks.each(function(s){ this.tasks.get(s).el.show();}.bind(this));
  }
  });

document.observe('dom:loaded', function()
{
    app = new App();
	settings = new Settings();
});
